package scfg.utils.trainging_results.delete;

import java.io.File;
import java.util.Scanner;

public class Run implements Comparable<Run> {
	enum SetSize {
		ONE, THREE, SMALL, LARGE
	};

	private int convSetSize() {
		switch (size) {
		case ONE:
			return 0;
		case THREE:
			return 1;
		case SMALL:
			return 2;
		case LARGE:
			return 3;
		default:
			return 4;
		}
	}

	enum RnaClass {
		tRNA, ECOLI, _5S, _16S, _23S, YEAST
	};

	private int convRnaClass() {
		switch (rnaClass) {
		case _5S:
			return 0;
		case _16S:
			return 1;
		case _23S:
			return 2;
		case ECOLI:
			return 3;
		case tRNA:
			return 4;
		case YEAST:
			return 5;
		default:
			return 6;
		}
	}

	private File f;
	private SetSize size;
	private boolean easy;
	private RnaClass rnaClass;
	StringBuilder contents;
	private double[] kh_params, kh_perc;
	private double[] nucleotideDist, pfold_params_u;
	private double[][] pfold_params_p;

	public double[] get_kh_params() {
		return kh_params;
	}

	public double[] get_pfold_params_u() {
		return pfold_params_u;
	}

	public double[][] get_pfold_params_p() {
		return pfold_params_p;
	}

	public Run(double[] nucDist, double[] kh_par, double[] kh_per,
			double[] pfold_u, double[][] pfold_bp) {
		this.nucleotideDist = nucDist;
		this.kh_params = kh_par;
		this.kh_perc = kh_per;
		this.pfold_params_u = pfold_u;
		this.pfold_params_p = pfold_bp;
	}

	public Run(File f, Scanner scan) {
		this.f = f;
		contents = new StringBuilder(f.getAbsolutePath()).append("\n");
		easy = f.getName().contains("easy");
		rnaClass = this.getRnaClass();
		size = this.getSize();
		kh_params = new double[3];
		pfold_params_u = new double[4];
		pfold_params_p = new double[4][4];

		while (scan.hasNext()) {
			String line = scan.nextLine();
			contents.append(line).append("\n");
			if (line.equals("Knudson-Hein Grammar Production Probabilites:"))
				parse_kh_params(scan);
			else if (line
					.equals("Pfold Grammar Un-Matched Production Probabilites:"))
				parse_pfold_params_u(scan);
			else if (line
					.equals("Pfold Grammar Base Pair Production Probabilites:")) {
				parse_pfold_params_p(scan);
				break;
			}
		}
	}

	private SetSize getSize() {
		if (f.getName().contains("_1_"))
			return SetSize.ONE;
		if (f.getName().contains("_3_"))
			return SetSize.THREE;
		if (f.getName().contains("_sm_"))
			return SetSize.SMALL;
		return SetSize.LARGE;
	}

	private RnaClass getRnaClass() {
		if (f.getName().contains("tRNA"))
			return RnaClass.tRNA;
		if (f.getName().contains("ecoli"))
			return RnaClass.ECOLI;
		if (f.getName().contains("5S"))
			return RnaClass._5S;
		if (f.getName().contains("16S"))
			return RnaClass._16S;
		if (f.getName().contains("23S"))
			return RnaClass._23S;
		return RnaClass.YEAST;
	}

	private void parse_kh_params(Scanner scan) {
		contents.append(scan.nextLine()).append("\n");
		for (int i = 0; i < 3; i++) {
			String line = scan.nextLine();
			contents.append(line).append("\n");
			String[] arr = line.split("\\(", 2);
			arr = arr[1].split("\\)", 2);
			if (arr[0].equals("*"))
				kh_params[i] = -1.0;
			else
				kh_params[i] = Double.parseDouble(arr[0]);
		}
	}

	private void parse_pfold_params_u(Scanner scan) {
		contents.append(scan.nextLine()).append("\n");
		for (int i = 0; i < 4; i++) {
			String line = scan.nextLine();
			contents.append(line).append("\n");
			String[] arr = line.split("\\(", 2);
			arr = arr[1].split("\\)", 2);
			if (arr[0].equals("*"))
				pfold_params_u[i] = -1.0;
			else
				pfold_params_u[i] = Double.parseDouble(arr[0]);
		}
	}

	private void parse_pfold_params_p(Scanner scan) {
		contents.append(scan.nextLine()).append("\n");
		contents.append(scan.nextLine()).append("\n");
		contents.append(scan.nextLine()).append("\n");
		for (int i = 0; i < 4; i++) {
			String line = scan.nextLine();
			contents.append(line).append("\n");
			String[] arr = line.replaceAll("x = ", "").trim().split(" +");
			for (int j = 0; j < 4; j++) {
				if (arr[j + 1].equals("*"))
					pfold_params_p[i][j] = -1.0;
				else
					pfold_params_p[i][j] = Double.parseDouble(arr[j + 1]);
			}
		}
	}

	@Override
	public String toString() {
		return contents.toString();
	}

	@Override
	public int compareTo(Run that) {
		if (this.convRnaClass() == that.convRnaClass())
			if (this.convSetSize() == that.convSetSize())
				return this.easy && that.easy ? 0 : this.easy ? -1 : 1;
			else
				return this.convSetSize() - that.convSetSize();
		return this.convRnaClass() - that.convRnaClass();
	}
}
